import {
  Controller,
  Delete,
  Get,
  Injectable,
  Module,
  Param,
  Put,
  Query,
  UseInterceptors,
} from "@nestjs/common";
import { PrismaClient } from "@prisma/client";
import {
  ArticleCommentService,
  ArticleCommentModule,
} from "src/article/comment.module";
import configuration from "src/common/configuration";
import { WebResult } from "src/common/web.result";
import { AdminLoginInterceptor } from "src/admin/interceptor/alogin.interceptor";
import { UserModule } from "src/user/user.module";

@Injectable()
export class AdminArticleCommentService {
  constructor(private readonly prisma: PrismaClient) {}

  async changeCommentState(commentID: number, newState: "pass" | "reject") {
    let review = await this.prisma.article_comment_review.findUnique({
      where: {
        comment_id: commentID,
      },
    });
    if (!review) {
      review = await this.prisma.article_comment_review.create({
        data: {
          comment_id: commentID,
          state: newState,
        },
      });
      return review ? true : false;
    }

    review = await this.prisma.article_comment_review.update({
      where: {
        comment_id: commentID,
      },
      data: {
        state: newState,
      },
    });
    return review ? true : false;
  }
}

@Controller("/admin/article/comment")
@UseInterceptors(AdminLoginInterceptor)
export class AdminArticleCommentController {
  constructor(
    private readonly prisma: PrismaClient,
    private readonly articleCommentService: ArticleCommentService,
    private readonly adminArticleCommentService: AdminArticleCommentService,
  ) {}

  @Put("/pass/:id")
  async passComment(
    @Param("id") id: string,
    @Query("notifyPublisher") notifyPublisher: string | boolean,
    @Query("notifyParentCommenter") notifyParentCommenter: string | boolean,
  ) {
    const commentID = parseInt(id);
    if (isNaN(commentID)) {
      return WebResult.failure(undefined, "参数错误");
    }
    if (notifyPublisher === "true") {
      notifyPublisher = true;
    }
    if (notifyParentCommenter === "true") {
      notifyParentCommenter = true;
    }
    const result = await this.adminArticleCommentService.changeCommentState(
      commentID,
      "pass",
    );
    if (!result) {
      return WebResult.failure(undefined, "pass失败");
    }

    if (configuration.email.enable) {
      if (notifyPublisher) {
        this.articleCommentService.notifyPublisherByCommentID(commentID);
      }
      if (notifyParentCommenter) {
        this.articleCommentService.notifyParentCommenterByCommentID(commentID);
      }
    }

    return WebResult.success(undefined, "pass成功");
  }

  @Put("/reject/:id")
  async rejectComment(@Param("id") id: string) {
    const commentID = parseInt(id);
    if (isNaN(commentID)) {
      return WebResult.failure(undefined, "参数错误");
    }
    const result = await this.adminArticleCommentService.changeCommentState(
      commentID,
      "reject",
    );
    return result
      ? WebResult.success(undefined, "reject成功")
      : WebResult.failure(undefined, "reject失败");
  }

  @Delete(["/:id", "/delete/:id"])
  async deleteCommentByID(@Param("id") id: string) {
    const commentID = parseInt(id);
    if (isNaN(commentID)) {
      return WebResult.failure(undefined, "comment id must be a number");
    }
    const comment = await this.prisma.article_comment.delete({
      where: {
        id: commentID,
      },
    });
    if (!comment) {
      return WebResult.failure(undefined, "删除失败，找不到该评论");
    }
    return WebResult.success(undefined, "删除成功");
  }

  @Get("/count")
  async getCommentsCount() {
    const count =
      await this.articleCommentService.getArticleCommentCount("all");
    return WebResult.success(count);
  }
  @Get("/page/:page")
  async getCommentsByPage(
    @Param("page") page: string,
    @Query("size") pageSize?: string,
  ) {
    const p = parseInt(page) || 1;
    const size = parseInt(pageSize);
    const comments = await this.articleCommentService.getArticleCommentsByPage(
      "all",
      p,
      size,
    );
    return WebResult.success(comments);
  }

  @Get("/reviewing/count")
  async getReviewingCommentsCount() {
    const count =
      await this.articleCommentService.getArticleCommentCount("reviewing");
    return WebResult.success(count);
  }
  @Get("/reviewing/page/:page")
  async getReviewingCommentsByPage(
    @Param("page") page: string,
    @Query("size") pageSize: string,
  ) {
    const p = parseInt(page) || 1;
    const size = parseInt(pageSize);
    const comments = await this.articleCommentService.getArticleCommentsByPage(
      "reviewing",
      p,
      size,
    );
    return WebResult.success(comments);
  }

  @Get("/pass/count")
  async getPassCommentsCount() {
    const count =
      await this.articleCommentService.getArticleCommentCount("pass");
    return WebResult.success(count);
  }
  @Get("/pass/page/:page")
  async getPassCommentsByPage(
    @Param("page") page: string,
    @Query("size") pageSize: string,
  ) {
    const p = parseInt(page) || 1;
    const size = parseInt(pageSize);
    const comments = await this.articleCommentService.getArticleCommentsByPage(
      "pass",
      p,
      size,
    );
    return WebResult.success(comments);
  }

  @Get("/reject/count")
  async getRejectCommentsCount() {
    const count =
      await this.articleCommentService.getArticleCommentCount("reject");
    return WebResult.success(count);
  }
  @Get("/reject/page/:page")
  async getRejectCommentsByPage(
    @Param("page") page: string,
    @Query("size") pageSize: string,
  ) {
    const p = parseInt(page) || 1;
    const size = parseInt(pageSize);
    const comments = await this.articleCommentService.getArticleCommentsByPage(
      "reject",
      p,
      size,
    );
    return WebResult.success(comments);
  }
}

@Module({
  imports: [UserModule, ArticleCommentModule],
  controllers: [AdminArticleCommentController],
  providers: [AdminArticleCommentService],
})
export class AdminArticleCommentModule {}
